// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//


#pragma once

#include <melon/conv.h>
#include <random>

namespace kumo::pollux::dwio::common {
    class RandGen {
    public:
        RandGen()
            : rand_{}, mt_{rand_()}, dist_(0, std::numeric_limits<int32_t>::max()) {
        }

        template<typename T>
        T gen(int32_t max) {
            return melon::to<T>(gen(max));
        }

        template<typename T>
        T gen(int32_t min, int32_t max) {
            return melon::to<T>(gen(min, max));
        }

        template<typename T>
        T gen() {
            return melon::to<T>(gen());
        }

        int32_t gen(int32_t min, int32_t max) {
            return std::uniform_int_distribution<int32_t>(min, max)(mt_);
        }

        int32_t gen(int32_t max) {
            return std::uniform_int_distribution<int32_t>(0, max)(mt_);
        }

        int32_t gen() {
            return dist_(mt_);
        }

    private:
        RandGen(const RandGen &) = delete;

        RandGen(RandGen &&) = delete;

        RandGen &operator=(const RandGen &) = delete;

        RandGen &operator=(RandGen &&) = delete;

    private:
        std::random_device rand_;
        std::mt19937 mt_;
        std::uniform_int_distribution<int32_t> dist_;
    };
} // namespace kumo::pollux::dwio::common
